package com.niiwoo.civet.account.service.local.refund.newRefund;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.account.constant.RedissonLockConstant;
import com.niiwoo.civet.account.dao.entity.AccountBase;
import com.niiwoo.civet.account.dao.mapper.AccountBaseMapperExt;
import com.niiwoo.civet.account.dto.common.AccountBatchTransOrderDTO;
import com.niiwoo.civet.account.enums.RefundStatusEnum;
import com.niiwoo.civet.account.service.local.refund.AccountRefundCommonLocalService;
import com.niiwoo.civet.base.enums.RefundBizStatusEnum;
import com.niiwoo.civet.trade.enums.BatchRefundTypeEnum;
import com.niiwoo.civet.trade.enums.RepayStatusEnum;
import com.niiwoo.civet.user.dto.response.LoginAccountResponseDTO;
import com.niiwoo.tripod.lanmao.enums.TransactionTypeEnum;
import com.niiwoo.tripod.provider.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * Created by dell on 2018/1/31.
 * 还款总流程服务
 */
@Slf4j
@Service
public class AccountRefundProcessLocalService {

    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private AccountRefundCommonLocalService accountRefundCommonLocalService;
    @Autowired
    private AccountRefundHandleLocalService accountRefundHandleLocalService;
    @Autowired
    private RefundBaseLocalService refundBaseLocalService;
    @Autowired
    private RefundQueryLocalService refundQueryLocalService;
    @Reference(version = "1.0.0")
    private com.niiwoo.civet.user.service.UserLoginAccountDubboService userLoginAccountDubboService;
    @Autowired
    private AccountBaseMapperExt accountBaseMapperExt;


    /**
     * 同步还款流程控制
     * localService 总入口
     * @param dto
     * @param
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public RefundBizStatusEnum pushTransOrderSync(AccountBatchTransOrderDTO dto,Boolean isNeedWithhold) throws ExecutionException, InterruptedException {
        log.info("pushTransOrderAppSync().init--,dto={},isNeedWithhold={}", JSON.toJSONString(dto),isNeedWithhold);
        RLock lock = redissonClient.getLock(new StringBuffer().append(RedissonLockConstant.REFUND_TRADE_TYPE).append(TransactionTypeEnum.enumOf(dto.getTradeType()).name()).append(RedissonLockConstant.CURRENT_PERIOD).append(dto.getProjectId()).append(RedissonLockConstant.JOIN_SIGN).append(dto.getCurrentPeriod()).toString());
        Long refundOrderId = null;
        RefundBizStatusEnum status = null;
        try {
            lock.lock();
            //查询标的ID和当前期数在还款订单表中是否存在处理中,处理成功,部分处理成功,存在则忽略
            int handingNum = accountRefundCommonLocalService.selectFromMasterRefundingProject(dto);
            log.info("正在处理标的-handingNum={}",handingNum);
            //插入还款订单
            refundOrderId = refundBaseLocalService.insertBatchTransOrder(dto);
            dto.setBatchTransOrderId(refundOrderId);
        } catch (Exception e) {
            log.error("pushTransOrderAppSync exception ", e);
            throw e;
        } finally {
            lock.unlock();
        }
        if (refundOrderId != null){
            //同步调用还款订单处理接口
            status = this.repaymentProcessSync(dto, refundOrderId,isNeedWithhold);
        }
        return status;

    }

    /**
     * 同步还款处理
     * @param dto
     * @param refundOrderId
     * @return
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public RefundBizStatusEnum repaymentProcessSync(AccountBatchTransOrderDTO dto, Long refundOrderId,Boolean isNeedWithhold) throws ExecutionException, InterruptedException {
//        RLock lock = redissonClient.getLock(new StringBuffer().append(RedissonLockConstant.REFUND_TRADE_TYPE).append(TransactionTypeEnum.enumOf(dto.getTradeType()).name()).append(RedissonLockConstant.REFUND_ACCOUNT).append(dto.getBorrowerUserId()).toString());
//
//        try {
//            lock.lock();
//            AccountBase account = refundQueryLocalService.getAccountBase(dto);
//            if (account == null) {
//                throw new BizException("ACC10004", "借款账户不存在");
//            }
//            if (dto.getIsWithHoldRefund()){
//                log.info("getIsWithHoldRefund=true,代扣预处理");
//                return accountRefundHandleLocalService.withholdRefundWithFreeze(dto,account,refundOrderId);
//            }
//            //金额不足且需要代扣(先代扣再还款)
//            if (isNeedWithhold && account.getAvailableAmount().compareTo(dto.getAmount())<0){
//                log.info("金额不足且需要代扣(先代扣再还款),availabelAmount={},dto.amount={}",account.getAvailableAmount(),dto.getAmount());
//                return accountRefundHandleLocalService.amountNotEnoughSync(dto, account, refundOrderId);
//            }
//            if (dto.getRepayStatus().equals(RepayStatusEnum.NORMAL.getCode()) && account.getAvailableAmount().compareTo(dto.getAmount()) < 0) {
//                throw new BizException("ACC10007");
//            } else if (dto.getRepayStatus().equals(RepayStatusEnum.BADLOANS.getCode())
//                    || dto.getRepayStatus().equals(RepayStatusEnum.OVERDUE.getCode())) {
//                log.info("标的已逾期，支持部分还款");
//                if (account.getAvailableAmount().compareTo(BigDecimal.ZERO) == 0){
//                    log.error("余额为0，不支持部分还款,projectId={}",dto.getProjectId());
//                    throw new BizException("ACC10007");
//                }else if (dto.getAmount().compareTo(account.getAvailableAmount()) > 0) {
//                    dto.setAmount(account.getAvailableAmount());
//                    log.info("部分还款，还款金额={},标的号={}",dto.getAmount(),dto.getProjectId());
//                }
//            }
//            return accountRefundHandleLocalService.amountEnoughSync(dto, account.getId(), account.getAccountNo(), refundOrderId);
//        } catch (BizException e) {
//            log.error("--repaymentProcessAppSync-BizException---", e);
//            //ACC10009 存管冻结预处理失败
//            //ACC10015 还款批量交易失败
//            //ACC10005 借款人银行卡信息不存在
//            //ACC10006 支付渠道不存在
//            if("ACC10005".equals(e.getErrorCode())|| "ACC10006".equals(e.getErrorCode() )) {
//                refundBaseLocalService.updateBatchTransOrderStatus(dto.getBatchRequestNo(), dto.getBatchTransOrderId(), RefundStatusEnum.FAIL);
//            }
//            throw e;
//        } finally {
//            lock.unlock();
//        }
        return null;
    }

    /**
     * 后台还款(job)，异步处理
     * @param dtoList
     * @param isNeedWithhold
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public void pushTransOrder(List<AccountBatchTransOrderDTO> dtoList, boolean isNeedWithhold) throws ExecutionException, InterruptedException {
        log.info("pushTransOrder(),isWithHold={}",isNeedWithhold);
        for (Iterator<AccountBatchTransOrderDTO> iterator = dtoList.iterator(); iterator.hasNext();){
            AccountBatchTransOrderDTO dto = iterator.next();
            log.info("pushTransOrder--,dto={}",JSON.toJSONString(dto));
            if (dto.getAmount() == null||dto.getAmount().compareTo(BigDecimal.ZERO) <= 0){
                iterator.remove();
                continue;
            }
            RLock lock = redissonClient.getLock(new StringBuffer().append(RedissonLockConstant.REFUND_TRADE_TYPE).append(TransactionTypeEnum.enumOf(dto.getTradeType()).name()).append(RedissonLockConstant.CURRENT_PERIOD).append(dto.getProjectId()).append(RedissonLockConstant.JOIN_SIGN).append(dto.getCurrentPeriod()).toString());
            if (lock.tryLock()) {
                try {
                    //查询标的ID和当前期数在还款订单表中是否存在处理中,处理成功,部分处理成功,存在则忽略
                    int handingNum = accountRefundCommonLocalService.selectFromMasterRefundingProject(dto);
                    log.info("正在处理标的和已成功数-handingNum={}",handingNum);
                    //插入还款订单
                    Long batchTransOrderId = refundBaseLocalService.insertBatchTransOrder(dto);
                    dto.setBatchTransOrderId(batchTransOrderId);

                } catch (Exception e) {
                    log.error("account-refund pushTransOrder failed，AccountBatchTransOrderDTO={}",JSON.toJSONString(dto), e);
                    iterator.remove();
                } finally {
                    lock.unlock();
                }
            }
        }
        //同调步用还款订单处理接口
        repaymentProcess(dtoList, isNeedWithhold);

        /*CompletableFuture.runAsync(()->{
            try {
            ·  repaymentProcess(dtoList, isNeedWithhold);
            } catch (ExecutionException|InterruptedException e) {
                log.error("repaymentProcess ExecutionException|InterruptedException ",e);
            }
        });*/
    }

    /**
     * 异步还款处理
     * @param dtoList
     * @param isNeedWithhold
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public void repaymentProcess(List<AccountBatchTransOrderDTO> dtoList, boolean isNeedWithhold) throws ExecutionException, InterruptedException {
//        for (AccountBatchTransOrderDTO dto:dtoList){
//            log.info("异步还款任务执行AccountBatchTransOrderDTO={}", JSON.toJSONString(dto));
//            RLock lock = redissonClient.getLock(new StringBuffer().append(RedissonLockConstant.REFUND_TRADE_TYPE).append(TransactionTypeEnum.enumOf(dto.getTradeType()).name()).append(RedissonLockConstant.REFUND_ACCOUNT).append(dto.getBorrowerUserId()).toString());
//            try {
//                lock.lock();
//                AccountBase account = refundQueryLocalService.getAccountBase(dto);
//                if (account == null) {
//                    throw new BizException("ACC10004", "借款人账户不存在");
//                }
//                log.info("AccountBase={}",JSON.toJSONString(account));
//                LoginAccountResponseDTO loginAccount = userLoginAccountDubboService.getLoginAccount(dto.getBorrowerUserId());
//                if (loginAccount == null) {
//                    throw new BizException("ACC5001", "登录账户不存在");
//                }
//                log.info("LoginAccountResponseDTO={}",JSON.toJSONString(loginAccount));
//                dto.setBorrowerUserMobileNo(loginAccount.getLoginMobileNo());
//                //如果余额不足
//                if (account.getAvailableAmount().compareTo(dto.getAmount()) < 0) {
//                    if (isNeedWithhold) {
//                        //代扣后再余额还款
//                        accountRefundHandleLocalService.amountNotEnough(dto, account, dto.getBatchTransOrderId());
//                        return;
//                    } else {
//                        log.info("借款账户可用余额不足,可用余额{},应还余额{}",account.getAvailableAmount(),dto.getAmount());
//                        //将还款订单状态改为失败(非垫付任务),直接更新成失败
//                        //11:00点，16：00：21：00点 走逾期还款不垫付流程
//                        if ((dto.getRepayStatus() == RepayStatusEnum.BADLOANS.getCode() || dto.getRepayStatus() == RepayStatusEnum.OVERDUE.getCode())
//                                && !dto.getBatchRefundType().equals(BatchRefundTypeEnum.NEED_GUARANTEE_REFUND.getValue())) {
//                            if (account.getAvailableAmount().compareTo(BigDecimal.ZERO)==0){
//                                refundBaseLocalService.updateBatchTransOrderStatus(dto.getBatchRequestNo(), dto.getBatchTransOrderId(), RefundStatusEnum.FAIL);
//                                return;
//                            }
//                            else {
//                                //有多少还多少
//                                BigDecimal canRefundAmount = dto.getAmount().compareTo(account.getAvailableAmount())>0? account.getAvailableAmount():dto.getAmount();
//                                dto.setAmount(canRefundAmount);
//                            }
//                        }
//                    }
//                }
//                //余额还款
//                accountRefundHandleLocalService.amountEnough(dto, account.getId(), account.getAccountNo(), dto.getBatchTransOrderId());
//            } catch (BizException e) {
//                log.error("repaymentProcess exception.", e);
//                //ACC10009 存管冻结预处理失败
//                //ACC10015 还款批量交易失败
//                //ACC10005 借款人银行卡信息不存在
//                //ACC10006 支付渠道不存在
//                if( "ACC10005".equals(e.getErrorCode())
//                    || "ACC10006".equals(e.getErrorCode() )) {
//                    refundBaseLocalService.updateBatchTransOrderStatus(dto.getBatchRequestNo(), dto.getBatchTransOrderId(), RefundStatusEnum.FAIL);
//                }
//            }finally {
//                lock.unlock();
//            }
//        }
    }

}
